package utils

import (
	"fmt"
	"math"

	"gorm.io/gorm"
)

// 分页请求参数
type PaginationParams struct {
	Page     int    `form:"page"`
	PageSize int    `form:"pageSize"`
	Sort     string `form:"sort"`
}

// 分页响应结构
type PaginationResult struct {
	Current     int           `json:"current"`
	PageSize    int           `json:"pageSize"`
	TotalItems  int64         `json:"totalItems"`
	TotalPages  int           `json:"totalPages"`
	HasPrev     bool          `json:"hasPrev"`
	HasNext     bool          `json:"hasNext"`
	Prev        int           `json:"prev"`
	Next        int           `json:"next"`
	Pages       []interface{} `json:"pages"`
	Data        interface{}   `json:"data"`
	RangeString string        `json:"rangeString"`
}

// 1️⃣ 计算分页参数（安全校验）
func NormalizePagination(p *PaginationParams) {
	if p.Page < 1 {
		p.Page = 1
	}
	if p.PageSize < 1 {
		p.PageSize = 10
	} else if p.PageSize > 100 {
		p.PageSize = 100
	}
}

// 2️⃣ 从数据库获取分页数据
func Paginate(db *gorm.DB, p *PaginationParams, model interface{}, result interface{}) (*PaginationResult, error) {
	var total int64
	db.Model(model).Count(&total)

	offset := (p.Page - 1) * p.PageSize
	query := db.Limit(p.PageSize).Offset(offset)

	if p.Sort != "" {
		query = query.Order(p.Sort)
	}

	if err := query.Find(result).Error; err != nil {
		return nil, err
	}

	totalPages := int(math.Ceil(float64(total) / float64(p.PageSize)))

	return BuildPaginationResult(p.Page, p.PageSize, totalPages, total, result), nil
}

// 3️⃣ 构造分页响应
func BuildPaginationResult(current, pageSize, totalPages int, totalItems int64, data interface{}) *PaginationResult {
	// 页码生成逻辑
	pages := []interface{}{}
	switch {
	case totalPages <= 6:
		for i := 1; i <= totalPages; i++ {
			pages = append(pages, i)
		}
	case current <= 4:
		for i := 1; i <= 6; i++ {
			pages = append(pages, i)
		}
		pages = append(pages, "…", totalPages)
	case current >= totalPages-3:
		pages = append(pages, 1, "…")
		for i := totalPages - 5; i <= totalPages; i++ {
			if i > 1 {
				pages = append(pages, i)
			}
		}
	default:
		pages = append(pages, 1, "…")
		for i := current - 2; i <= current+2; i++ {
			pages = append(pages, i)
		}
		pages = append(pages, "…", totalPages)
	}

	hasPrev := current > 1
	hasNext := current < totalPages
	prev := 0
	next := 0
	if hasPrev {
		prev = current - 1
	}
	if hasNext {
		next = current + 1
	}

	// 当前范围
	start := (current-1)*pageSize + 1
	end := start + pageSize - 1
	if end > int(totalItems) {
		end = int(totalItems)
	}
	rangeStr := ""
	if totalItems > 0 {
		rangeStr = "显示第 " + IntToStr(start) + "-" + IntToStr(end) + " 条，共 " + IntToStr(int(totalItems)) + " 条"
	}

	return &PaginationResult{
		Current:     current,
		PageSize:    pageSize,
		TotalItems:  totalItems,
		TotalPages:  totalPages,
		HasPrev:     hasPrev,
		HasNext:     hasNext,
		Prev:        prev,
		Next:        next,
		Pages:       pages,
		Data:        data,
		RangeString: rangeStr,
	}
}

// 工具函数：int转string
func IntToStr(i int) string {
	return fmt.Sprintf("%d", i)
}
